package com.snow.datasource.autoconfigure;

import com.snow.datasource.config.DruidDynamicDataSourceConfiguration;
import com.snow.datasource.config.HealthConfig;
import com.snow.datasource.config.StrategyConfig;
import com.snow.datasource.creator.DruidCreator;
import com.snow.datasource.advisor.SnowDataSourceAnnotationAdvisor;
import com.snow.datasource.advisor.SnowDataSourceAnnotationInterceptor;
import com.snow.datasource.properties.SnowFlakeProperties;
import com.snow.datasource.provider.ISnowProvider;
import com.snow.datasource.provider.SnowDataSourceProvider;
import com.snow.datasource.route.SnowRoutingDataSource;
import com.snow.datasource.strategy.LoadBalanceStrategy;
import com.snow.datasource.strategy.manage.impl.ManageStrategyImpl;
import lombok.AllArgsConstructor;
import lombok.Data;
import org.springframework.aop.Advisor;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.*;

/**
 * 雪花数据源配置入口类
 *
 * @Description
 * @Author fanxl 315620726@qq.com
 * @Date 2020/12/16
 **/
@Data
@Configuration
@Import({DruidDynamicDataSourceConfiguration.class, StrategyConfig.class,HealthConfig.class})
@EnableConfigurationProperties(SnowFlakeProperties.class)
@EnableAspectJAutoProxy(proxyTargetClass = true)
@AllArgsConstructor
public class SnowAutoConfiguration {
    /**
     * 数据源属性配置
     */
    private final SnowFlakeProperties snowFlakeProperties;


    @Bean
    @ConditionalOnMissingBean
    public ISnowProvider getSnowProvider(){
        return new SnowDataSourceProvider(snowFlakeProperties.getDatasource());
    }

    @Bean
    @ConditionalOnMissingBean
    @ConditionalOnClass(DruidCreator.class)
    public SnowRoutingDataSource getSnowRoutingDataSource(ISnowProvider iSnowProvider){
        SnowRoutingDataSource snowRoutingDataSource = new SnowRoutingDataSource();
        snowRoutingDataSource.setISnowProvider(iSnowProvider);
        snowRoutingDataSource.setPrimary(snowFlakeProperties.getPrimary());
        return snowRoutingDataSource;
    }
    @Bean
    @ConditionalOnMissingBean
    public DruidCreator getDruidCreator(){
        return new DruidCreator(snowFlakeProperties.getDruid());
    }

    @Bean
    @ConditionalOnMissingBean
    @Role(BeanDefinition.ROLE_INFRASTRUCTURE)
    public Advisor snowDataSourceAnnotationAdvisor() {
        SnowDataSourceAnnotationInterceptor interceptor = new SnowDataSourceAnnotationInterceptor(snowFlakeProperties.isAllowedPublicOnly());
        SnowDataSourceAnnotationAdvisor  advisor = new SnowDataSourceAnnotationAdvisor(interceptor);
        advisor.setOrder(snowFlakeProperties.getOrder());
        return advisor;
    }

}
